home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / vidhrdw / cischeat.c < prev    next >
C/C++ Source or Header  |  2000-05-13  |  32KB  |  1,080 lines

  1. /***************************************************************************
  2.  
  3.                         Cisco Heat & F1 GrandPrix Star
  4.                             (c) 1990 & 1991 Jaleco
  5.  
  6.  
  7.                     driver by Luca Elia (eliavit@unina.it)
  8.  
  9.  
  10. Note:    if MAME_DEBUG is defined, pressing Z with:
  11.  
  12.         Q,W,E        shows scroll 0,1,2
  13.         R,T            shows road 0,1
  14.         A,S,D,F        shows sprites with priority 0,1,2,3
  15.         N            shows sprites attribute
  16.         M            disables sprites zooming
  17.         U            toggles the display of some hardware registers'
  18.                     values ($80000/2/4/6)
  19.  
  20.         Keys can be used togheter!
  21.         Additionally, layers can be disabled, writing to $82400
  22.         (fake video register):
  23.  
  24.             ---- ---- --54 ----        Enable Road 1,0
  25.             ---- ---- ---- 3---        Enable Sprites
  26.             ---- ---- ---- -210        Enable Scroll 2,1,0
  27.  
  28.         0 is the same as 0x3f
  29.  
  30.  
  31. ----------------------------------------------------------------------
  32. Video Section Summary        [ Cisco Heat ]            [ F1 GP Star ]
  33. ----------------------------------------------------------------------
  34.  
  35. [ 3 Scrolling Layers ]
  36.     see Megasys1.c
  37.  
  38.         Tile Format:
  39.  
  40.                 Colour        fedc b--- ---- ----        fedc ---- ---- ----
  41.                 Code        ---- -a98 7654 3210        ---- ba98 7654 3210
  42.  
  43.         Layer Size:            May be different from Megasys1?
  44.  
  45. [ 2 Road Layers ]
  46.     Each of the 256 (not all visible) lines of the screen
  47.     can display any of the lines of gfx in ROM, which are
  48.     larger than the sceen and can therefore be scrolled
  49.  
  50.                 Line Width            1024                    1024
  51.                 Zoom                No                        Yes
  52.  
  53. [ 256 Sprites ]
  54.     Each Sprite is up to 256x256 pixels (!) and can be zoomed in and out.
  55.     See below.
  56.  
  57.  
  58. ***************************************************************************/
  59.  
  60. #include "driver.h"
  61. #include "drivers/megasys1.h"
  62. #include "vidhrdw/generic.h"
  63.  
  64. /* Variables only used here: */
  65.  
  66. static int cischeat_ip_select;
  67. #ifdef MAME_DEBUG
  68. static int debugsprites;    // For debug purposes
  69. #endif
  70.  
  71. /* Variables that driver has access to: */
  72. unsigned char *cischeat_roadram[2];
  73.  
  74. /* Variables defined in driver: */
  75.  
  76.  
  77. /***************************************************************************
  78.  
  79.                                 vh_start
  80.  
  81. ***************************************************************************/
  82.  
  83. /**************************************************************************
  84.                                 [ Cisco Heat ]
  85. **************************************************************************/
  86.  
  87. /* 32 colour codes for the tiles */
  88. int cischeat_vh_start(void)
  89. {
  90.     if (megasys1_vh_start() == 0)
  91.     {
  92.          megasys1_bits_per_color_code = 5;
  93.          return 0;
  94.     }
  95.     else    return 1;
  96. }
  97.  
  98.  
  99.  
  100. /**************************************************************************
  101.                             [ F1 GrandPrix Star ]
  102. **************************************************************************/
  103.  
  104. /* 16 colour codes for the tiles */
  105. int f1gpstar_vh_start(void)
  106. {
  107.     if (megasys1_vh_start() == 0)
  108.     {
  109.          megasys1_bits_per_color_code = 4;
  110.          return 0;
  111.     }
  112.     else    return 1;
  113. }
  114.  
  115.  
  116.  
  117. /***************************************************************************
  118.  
  119.                         Hardware registers access
  120.  
  121. ***************************************************************************/
  122.  
  123. /*    This function returns the status of the shift (ACTIVE_LOW):
  124.  
  125.         1 - low  shift
  126.         0 - high shift
  127.  
  128.     and allows the shift to be handled using two buttons */
  129.  
  130. static int read_shift(void)
  131. {
  132.     static int ret = 1; /* start with low shift */
  133.     switch ( (readinputport(0) >> 2) & 3 )
  134.     {
  135.         case 1 : ret = 1;    break;    // low  shift: button 3
  136.         case 2 : ret = 0;    break;    // high shift: button 4
  137.     }
  138.     return ret;
  139. }
  140.  
  141.  
  142. /*
  143.     F1 GP Star has a real pedal, while Cisco Heat's is connected to
  144.     a switch. The Former game stores, during boot, the value that
  145.     corresponds to the pedal not pressed, and compares against it:
  146.  
  147.     The value returned must decrease when the pedal is pressed.
  148.     We support just 2 values for now..
  149. */
  150.  
  151. static int read_accelerator(void)
  152. {
  153.     if (readinputport(0) & 1)    return 0x00;    // pedal pressed
  154.     else                        return 0xff;
  155. }
  156.  
  157. /**************************************************************************
  158.                                 [ Cisco Heat ]
  159. **************************************************************************/
  160.  
  161. READ_HANDLER( cischeat_vregs_r )
  162. {
  163.     switch (offset)
  164.     {
  165.         case 0x0000 : return readinputport(1);    // Coins
  166.         case 0x0002 : return readinputport(2) + (read_shift()<<1);    // Buttons
  167.         case 0x0004 : return readinputport(3);    // Motor Limit Switches
  168.         case 0x0006 : return readinputport(4);    // DSW 1 & 2
  169.         case 0x0010 :
  170.             switch (cischeat_ip_select & 0x3)
  171.             {
  172.                 case 0 : return readinputport(6);    // Driving Wheel
  173.                 case 1 : return 0xFFFF;                // Cockpit: Up / Down Position?
  174.                 case 2 : return 0xFFFF;                // Cockpit: Left / Right Position?
  175.                 default: return 0xFFFF;
  176.             }
  177.  
  178.         case 0x2200 : return readinputport(5);    // DSW 3 (4 bits)
  179.         case 0x2300 : return soundlatch2_r(0);    // From sound cpu
  180.  
  181.         default:    SHOW_READ_ERROR("vreg %04X read!",offset);
  182.                     return READ_WORD(&megasys1_vregs[offset]);
  183.     }
  184. }
  185.  
  186. /**************************************************************************
  187.                             [ F1 GrandPrix Star ]
  188. **************************************************************************/
  189.  
  190.  
  191. READ_HANDLER( f1gpstar_vregs_r )
  192. {
  193.  
  194.     switch (offset)
  195.     {
  196.         case 0x0000 :    // DSW 1&2: coinage changes with Country
  197.         {
  198.             int val = readinputport(1);
  199.             if (val & 0x0200)    return readinputport(6) | val;     // JP, US
  200.             else                return readinputport(7) | val;     // UK, FR
  201.         }
  202.  
  203. //        case 0x0002 :    return 0xFFFF;
  204.         case 0x0004 :    return readinputport(2) + (read_shift()<<5);    // Buttons
  205.         case 0x0006 :    return readinputport(3);    // ? Read at boot only
  206.         case 0x0008 :    return soundlatch2_r(0);    // From sound cpu
  207.         case 0x000c :    return readinputport(4);    // DSW 3
  208.  
  209.         case 0x0010 :    // Accel + Driving Wheel
  210.             return (read_accelerator()&0xff) + ((readinputport(5)&0xff)<<8);
  211.  
  212.         default:        SHOW_READ_ERROR("vreg %04X read!",offset);
  213.                         return READ_WORD(&megasys1_vregs[offset]);
  214.     }
  215. }
  216.  
  217. /**************************************************************************
  218.                                 [ Cisco Heat ]
  219. **************************************************************************/
  220.  
  221. WRITE_HANDLER( cischeat_vregs_w )
  222. {
  223. int old_data, new_data;
  224.  
  225.     old_data = READ_WORD(&megasys1_vregs[offset]);
  226.     COMBINE_WORD_MEM(&megasys1_vregs[offset],data);
  227.     new_data  = READ_WORD(&megasys1_vregs[offset]);
  228.  
  229.     switch (offset)
  230.     {
  231.          case 0x0000   :    // leds
  232.              osd_led_w(0, (new_data >> 4) & 1 );
  233.             osd_led_w(1, (new_data >> 5) & 1 );
  234.             break;
  235.  
  236.         case 0x0002   :    // ?? 91/1/91/1 ...
  237.             break;
  238.  
  239.          case 0x0004   :    // motor (seat?)
  240.             osd_led_w(2, (new_data != old_data) ? 1 : 0);
  241.              break;
  242.  
  243.          case 0x0006   :    // motor (wheel?)
  244.             break;
  245.  
  246.         case 0x0010   : cischeat_ip_select = new_data;    break;
  247.         case 0x0012   : break; // value above + 1
  248.  
  249.         case 0x2000+0 : MEGASYS1_VREG_SCROLL(0,x)        break;
  250.         case 0x2000+2 : MEGASYS1_VREG_SCROLL(0,y)        break;
  251.         case 0x2000+4 : MEGASYS1_VREG_FLAG(0)            break;
  252.  
  253.         case 0x2008+0 : MEGASYS1_VREG_SCROLL(1,x)        break;
  254.         case 0x2008+2 : MEGASYS1_VREG_SCROLL(1,y)        break;
  255.         case 0x2008+4 : MEGASYS1_VREG_FLAG(1)            break;
  256.  
  257.         case 0x2100+0 : MEGASYS1_VREG_SCROLL(2,x)        break;
  258.         case 0x2100+2 : MEGASYS1_VREG_SCROLL(2,y)        break;
  259.         case 0x2100+4 : MEGASYS1_VREG_FLAG(2)            break;
  260.  
  261.         case 0x2108   : break;    // ? written with 0 only
  262.         case 0x2208   : break;    // watchdog reset
  263.  
  264.         case 0x2300   :    /* Sound CPU: reads latch during int 4, and stores command */
  265.                         soundlatch_w(0,new_data);
  266.                         cpu_cause_interrupt(3,4);
  267.                         break;
  268.  
  269.         /* Not sure about this one.. */
  270.         case 0x2308   :    cpu_set_reset_line(1, (new_data & 2) ? ASSERT_LINE : CLEAR_LINE );
  271.                         cpu_set_reset_line(2, (new_data & 2) ? ASSERT_LINE : CLEAR_LINE );
  272.                         cpu_set_reset_line(3, (new_data & 1) ? ASSERT_LINE : CLEAR_LINE );
  273.                         break;
  274.  
  275.         default: SHOW_WRITE_ERROR("vreg %04X <- %04X",offset,data);
  276.     }
  277. }
  278.  
  279.  
  280. /**************************************************************************
  281.                             [ F1 GrandPrix Star ]
  282. **************************************************************************/
  283.  
  284. WRITE_HANDLER( f1gpstar_vregs_w )
  285. {
  286. int old_data, new_data;
  287.  
  288.     old_data = READ_WORD(&megasys1_vregs[offset]);
  289.     COMBINE_WORD_MEM(&megasys1_vregs[offset],data);
  290.     new_data  = READ_WORD(&megasys1_vregs[offset]);
  291.  
  292.     switch (offset)
  293.     {
  294. /*
  295. CPU #0 PC 00234A : Warning, vreg 0000 <- 0000
  296. CPU #0 PC 002350 : Warning, vreg 0002 <- 0000
  297. CPU #0 PC 00235C : Warning, vreg 0006 <- 0000
  298. */
  299.         // "shudder" motors, leds
  300.         case 0x0004   :
  301.         case 0x0014   :
  302.  
  303.             osd_led_w(0, (new_data >> 2) & 1 );    // 1p start lamp
  304.             osd_led_w(1, (new_data >> 5) & 1 );    // 2p start lamp?
  305.  
  306.             // wheel | seat motor
  307.             osd_led_w(2, ((new_data >> 3) | (new_data >> 4)) & 1 );
  308.  
  309.             break;
  310.  
  311.         /* Usually written in sequence, but not always */
  312.         case 0x0008   :    soundlatch_w(0,new_data);    break;
  313.         case 0x0018   :    cpu_cause_interrupt(3,4);    break;
  314.  
  315.         case 0x0010   :    break;
  316.  
  317.         case 0x2000+0 : MEGASYS1_VREG_SCROLL(0,x)        break;
  318.         case 0x2000+2 : MEGASYS1_VREG_SCROLL(0,y)        break;
  319.         case 0x2000+4 : MEGASYS1_VREG_FLAG(0)            break;
  320.  
  321.         case 0x2008+0 : MEGASYS1_VREG_SCROLL(1,x)        break;
  322.         case 0x2008+2 : MEGASYS1_VREG_SCROLL(1,y)        break;
  323.         case 0x2008+4 : MEGASYS1_VREG_FLAG(1)            break;
  324.  
  325.         case 0x2100+0 : MEGASYS1_VREG_SCROLL(2,x)        break;
  326.         case 0x2100+2 : MEGASYS1_VREG_SCROLL(2,y)        break;
  327.         case 0x2100+4 : MEGASYS1_VREG_FLAG(2)            break;
  328.  
  329.         case 0x2108   : break;    // ? written with 0 only
  330.         case 0x2208   : break;    // watchdog reset
  331.  
  332.         /* Not sure about this one. Values: $10 then 0, $7 then 0 */
  333.         case 0x2308   :    cpu_set_reset_line(1, (new_data & 1) ? ASSERT_LINE : CLEAR_LINE );
  334.                         cpu_set_reset_line(2, (new_data & 2) ? ASSERT_LINE : CLEAR_LINE );
  335.                         cpu_set_reset_line(3, (new_data & 4) ? ASSERT_LINE : CLEAR_LINE );
  336.                         break;
  337.  
  338.         default:        SHOW_WRITE_ERROR("vreg %04X <- %04X",offset,data);
  339.     }
  340. }
  341.  
  342.  
  343.  
  344. /***************************************************************************
  345.                                 Road Drawing
  346. ***************************************************************************/
  347.  
  348. #define ROAD_COLOR_CODES    64
  349. #define ROAD_COLOR(_x_)    ((_x_) & (ROAD_COLOR_CODES-1))
  350.  
  351. /* horizontal size of 1 line and 1 tile of the road */
  352. #define X_SIZE (1024)
  353. #define TILE_SIZE (64)
  354.  
  355.  
  356. /**************************************************************************
  357.                                 [ Cisco Heat ]
  358. **************************************************************************/
  359.  
  360. /*
  361.     Road format:
  362.  
  363.     Offset        Data
  364.  
  365.     00.w        Code
  366.  
  367.     02.w        X Scroll
  368.  
  369.     04.w        fedc ---- ---- ----        unused?
  370.                 ---- ba98 ---- ----        Priority
  371.                 ---- ---- 76-- ----        unused?
  372.                 ---- ---- --54 3210        Color
  373.  
  374.     06.w        Unused
  375.  
  376. */
  377.  
  378. void cischeat_mark_road_colors(int road_num)
  379. {
  380.     int i, color, colmask[ROAD_COLOR_CODES], sy;
  381.  
  382.     int gfx_num                    =    (road_num & 1) ? 4 : 3;
  383.     struct GfxDecodeInfo gfx    =    Machine->drv->gfxdecodeinfo[gfx_num];
  384.     int total_elements            =    Machine->gfx[gfx_num]->total_elements;
  385.     unsigned int *pen_usage        =    Machine->gfx[gfx_num]->pen_usage;
  386. //    int total_color_codes        =    gfx.total_color_codes;
  387.     int color_codes_start        =    gfx.color_codes_start;
  388.     unsigned char *roadram        =    cischeat_roadram[road_num & 1];
  389.  
  390.     int min_y = Machine->drv->visible_area. min_y;
  391.     int max_y = Machine->drv->visible_area. max_y;
  392.  
  393.     for (color = 0 ; color < ROAD_COLOR_CODES ; color++) colmask[color] = 0;
  394.  
  395.     /* Let's walk from the top to the bottom of the visible screen */
  396.     for (sy = min_y ; sy <= max_y ; sy ++)
  397.     {
  398.         int code    = READ_WORD(&roadram[sy*8 + 0]);
  399.         int attr    = READ_WORD(&roadram[sy*8 + 4]);
  400.             color    = ROAD_COLOR(attr);
  401.  
  402.         /* line number converted to tile number (each tile is TILE_SIZE x 1) */
  403.         code    = code * (X_SIZE/TILE_SIZE);
  404.  
  405.         for (i = 0; i < (X_SIZE/TILE_SIZE); i++)
  406.             colmask[color] |= pen_usage[(code + i) % total_elements];
  407.     }
  408.  
  409.     for (color = 0; color < ROAD_COLOR_CODES; color++)
  410.      for (i = 0; i < 16; i++)
  411.       if (colmask[color] & (1 << i)) palette_used_colors[16 * color + i + color_codes_start] = PALETTE_COLOR_USED;
  412. }
  413.  
  414.  
  415.  
  416. /*
  417.     Draw road in the given bitmap. The priority1 and priority2 parameters
  418.     specify the range of lines to draw
  419. */
  420.  
  421. void cischeat_draw_road(struct osd_bitmap *bitmap, int road_num, int priority1, int priority2, int transparency)
  422. {
  423.  
  424.     int curr_code,sx,sy;
  425.     int min_priority, max_priority;
  426.  
  427.     struct rectangle rect        =    Machine->drv->visible_area;
  428.     unsigned char *roadram        =    cischeat_roadram[road_num & 1];
  429.     struct GfxElement *gfx        =    Machine->gfx[(road_num & 1)?4:3];
  430.  
  431.     int min_y = rect.min_y;
  432.     int max_y = rect.max_y;
  433.  
  434.     int max_x = rect.max_x;
  435.  
  436.     if (priority1 < priority2)    {    min_priority = priority1;    max_priority = priority2; }
  437.     else                        {    min_priority = priority2;    max_priority = priority1; }
  438.  
  439.     /* Move the priority values in place */
  440.     min_priority = (min_priority & 7) * 0x100;
  441.     max_priority = (max_priority & 7) * 0x100;
  442.  
  443.     /* Let's draw from the top to the bottom of the visible screen */
  444.     for (sy = min_y ; sy <= max_y ; sy ++)
  445.     {
  446.         int code    = READ_WORD(&roadram[sy*8 + 0]);
  447.         int xscroll = READ_WORD(&roadram[sy*8 + 2]);
  448.         int attr    = READ_WORD(&roadram[sy*8 + 4]);
  449.  
  450.         /* high byte is a priority information */
  451.         if ( ((attr & 0x700) < min_priority) || ((attr & 0x700) > max_priority) )
  452.             continue;
  453.  
  454.         /* line number converted to tile number (each tile is TILE_SIZE x 1) */
  455.         code    = code * (X_SIZE/TILE_SIZE);
  456.  
  457.         xscroll %= X_SIZE;
  458.         curr_code = code + xscroll/TILE_SIZE;
  459.  
  460.         for (sx = -(xscroll%TILE_SIZE) ; sx <= max_x ; sx +=TILE_SIZE)
  461.         {
  462.             drawgfx(bitmap,gfx,
  463.                     curr_code++,
  464.                     ROAD_COLOR(attr),
  465.                     0,0,
  466.                     sx,sy,
  467.                     &rect,
  468.                     transparency,15);
  469.  
  470.             /* wrap around */
  471.             if (curr_code%(X_SIZE/TILE_SIZE)==0)    curr_code = code;
  472.         }
  473.     }
  474.  
  475. }
  476.  
  477.  
  478.  
  479.  
  480.  
  481.  
  482.  
  483. /**************************************************************************
  484.                             [ F1 GrandPrix Star ]
  485. **************************************************************************/
  486.  
  487.  
  488. /*
  489.     Road format:
  490.  
  491.     Offset        Data
  492.  
  493.     00.w        fedc ---- ---- ----        Priority
  494.                 ---- ba98 7654 3210        X Scroll (After Zoom)
  495.  
  496.     02.w        fedc ba-- ---- ----        unused?
  497.                 ---- --98 7654 3210        X Zoom
  498.  
  499.     04.w        fe-- ---- ---- ----        unused?
  500.                 --dc ba98 ---- ----        Color
  501.                 ---- ---- 7654 3210        ?
  502.  
  503.     06.w        Code
  504.  
  505.  
  506.     Imagine an "empty" line, 2 * X_SIZE wide, with the gfx from
  507.     the ROM - whose original size is X_SIZE - in the middle.
  508.  
  509.     Zooming acts on this latter and can shrink it to 1 pixel or
  510.     widen it to 2 * X_SIZE, while *keeping it centered* in the
  511.     empty line.    Scrolling acts on the resulting line.
  512.  
  513. */
  514.  
  515. void f1gpstar_mark_road_colors(int road_num)
  516. {
  517.     int i, color, colmask[ROAD_COLOR_CODES], sy;
  518.  
  519.     int gfx_num                    =    (road_num & 1) ? 4 : 3;
  520.     struct GfxDecodeInfo gfx    =    Machine->drv->gfxdecodeinfo[gfx_num];
  521.     int total_elements            =    Machine->gfx[gfx_num]->total_elements;
  522.     unsigned int *pen_usage        =    Machine->gfx[gfx_num]->pen_usage;
  523. //    int total_color_codes        =    gfx.total_color_codes;
  524.     int color_codes_start        =    gfx.color_codes_start;
  525.     unsigned char *roadram        =    cischeat_roadram[road_num & 1];
  526.  
  527.     int min_y = Machine->drv->visible_area.min_y;
  528.     int max_y = Machine->drv->visible_area.max_y;
  529.  
  530.     for (color = 0 ; color < ROAD_COLOR_CODES ; color++) colmask[color] = 0;
  531.  
  532.     /* Let's walk from the top to the bottom of the visible screen */
  533.     for (sy = min_y ; sy <= max_y ; sy ++)
  534.     {
  535.         int code    = READ_WORD(&roadram[sy*8 + 6]);
  536.         int attr    = READ_WORD(&roadram[sy*8 + 4]);
  537.             color    = ROAD_COLOR(attr>>8);
  538.  
  539.         /* line number converted to tile number (each tile is TILE_SIZE x 1) */
  540.         code    = code * (X_SIZE/TILE_SIZE);
  541.  
  542.         for (i = 0; i < (X_SIZE/TILE_SIZE); i++)
  543.             colmask[color] |= pen_usage[(code + i) % total_elements];
  544.     }
  545.  
  546.     for (color = 0; color < ROAD_COLOR_CODES; color++)
  547.      for (i = 0; i < 16; i++)
  548.       if (colmask[color] & (1 << i)) palette_used_colors[16 * color + i + color_codes_start] = PALETTE_COLOR_USED;
  549. }
  550.  
  551.  
  552.  
  553. /*
  554.     Draw road in the given bitmap. The priority1 and priority2 parameters
  555.     specify the range of lines to draw
  556. */
  557.  
  558. void f1gpstar_draw_road(struct osd_bitmap *bitmap, int road_num, int priority1, int priority2, int transparency)
  559. {
  560.     int sx,sy;
  561.     int xstart;
  562.     int min_priority, max_priority;
  563.  
  564.     struct rectangle rect        =    Machine->drv->visible_area;
  565.     unsigned char *roadram        =    cischeat_roadram[road_num & 1];
  566.     struct GfxElement *gfx        =    Machine->gfx[(road_num & 1)?4:3];
  567.  
  568.     int min_y = rect.min_y;
  569.     int max_y = rect.max_y;
  570.  
  571.     int max_x = rect.max_x << 16;    // use fixed point values (16.16), for accuracy
  572.  
  573.     if (priority1 < priority2)    {    min_priority = priority1;    max_priority = priority2; }
  574.     else                        {    min_priority = priority2;    max_priority = priority1; }
  575.  
  576.     /* Move the priority values in place */
  577.     min_priority = (min_priority & 7) * 0x1000;
  578.     max_priority = (max_priority & 7) * 0x1000;
  579.  
  580.     /* Let's draw from the top to the bottom of the visible screen */
  581.     for (sy = min_y ; sy <= max_y ; sy ++)
  582.     {
  583.         int xscale, xdim;
  584.  
  585.         int xscroll    = READ_WORD(&roadram[sy*8 + 0]);
  586.         int xzoom    = READ_WORD(&roadram[sy*8 + 2]);
  587.         int attr    = READ_WORD(&roadram[sy*8 + 4]);
  588.         int code    = READ_WORD(&roadram[sy*8 + 6]);
  589.  
  590.         /* highest nibble is a priority information */
  591.         if ( ((xscroll & 0x7000) < min_priority) || ((xscroll & 0x7000) > max_priority) )
  592.             continue;
  593.  
  594.         /* zoom code range: 000-3ff        scale range: 0.0-2.0 */
  595.         xscale = ( ((xzoom & 0x3ff)+1) << (16+1) ) / 0x400;
  596.  
  597.         /* line number converted to tile number (each tile is TILE_SIZE x 1) */
  598.         code    = code * (X_SIZE/TILE_SIZE);
  599.  
  600.         /* dimension of a tile after zoom */
  601.         xdim = TILE_SIZE * xscale;
  602.  
  603.         xscroll %= 2 * X_SIZE;
  604.  
  605.         xstart  = (X_SIZE - xscroll) * 0x10000;
  606.         xstart -= (X_SIZE * xscale) / 2;
  607.  
  608.         /* let's approximate to the nearest greater integer value
  609.            to avoid holes in between tiles */
  610.         xscale += (1<<16)/TILE_SIZE;
  611.  
  612.         /* Draw the line */
  613.         for (sx = xstart ; sx <= max_x ; sx += xdim)
  614.         {
  615.             drawgfxzoom(bitmap,gfx,
  616.                         code++,
  617.                         ROAD_COLOR(attr>>8),
  618.                         0,0,
  619.                         sx / 0x10000, sy,
  620.                         &rect,
  621.                         transparency,15,
  622.                         xscale, 1 << 16);
  623.  
  624.             /* stop when the end of the line of gfx is reached */
  625.             if ((code % (X_SIZE/TILE_SIZE)) == 0)    break;
  626.         }
  627.  
  628.     }
  629.  
  630. }
  631.  
  632.  
  633.  
  634.  
  635. /***************************************************************************
  636.  
  637.                             Sprites Drawing
  638.  
  639. ***************************************************************************/
  640.  
  641. #define SIGN_EXTEND_POS(_var_)    {_var_ &= 0x3ff; if (_var_ > 0x1ff) _var_ -= 0x400;}
  642. #define SPRITE_COLOR_CODES    (0x80)
  643. #define SPRITE_COLOR(_x_)    ((_x_) & (SPRITE_COLOR_CODES - 1))
  644. #define SHRINK(_org_,_fact_) ( ( (_org_) << 16 ) * (_fact_ & 0xff) / 0x80 )
  645.  
  646.  
  647. /* Mark colors used by visible sprites */
  648.  
  649. static void cischeat_mark_sprite_colors(void)
  650. {
  651.     int i, color, colmask[SPRITE_COLOR_CODES];
  652.     unsigned int *pen_usage    =    Machine->gfx[5]->pen_usage;
  653.     int total_elements        =    Machine->gfx[5]->total_elements;
  654.     int color_codes_start    =    Machine->drv->gfxdecodeinfo[5].color_codes_start;
  655.  
  656.     int xmin = Machine->drv->visible_area.min_x;
  657.     int xmax = Machine->drv->visible_area.max_x;
  658.     int ymin = Machine->drv->visible_area.min_y;
  659.     int ymax = Machine->drv->visible_area.max_y;
  660.  
  661.     unsigned char        *source    = spriteram;
  662.     const unsigned char *finish    = source + 0x1000;
  663.  
  664.     for (color = 0 ; color < SPRITE_COLOR_CODES ; color++) colmask[color] = 0;
  665.  
  666.     for (; source < finish; source += 0x10 )
  667.     {
  668.         int sx, sy, xzoom, yzoom;
  669.         int xdim, ydim, xnum, ynum;
  670.         int code, attr, size;
  671.  
  672.          size    =    READ_WORD(&source[0x00]);
  673.         if (size & 0x1000)    continue;
  674.  
  675.         /* number of tiles */
  676.         xnum    =    ( (size & 0x0f) >> 0 ) + 1;
  677.         ynum    =    ( (size & 0xf0) >> 4 ) + 1;
  678.  
  679.         xzoom    =    READ_WORD(&source[0x02]);
  680.         yzoom    =    READ_WORD(&source[0x04]);
  681.  
  682.         sx        =    READ_WORD(&source[0x06]);
  683.         sy        =    READ_WORD(&source[0x08]);
  684.         SIGN_EXTEND_POS(sx)
  685.         SIGN_EXTEND_POS(sy)
  686.  
  687.         /* dimension of the sprite after zoom */
  688.         xdim    =    ( SHRINK(16 * xnum, xzoom) ) >> 16;
  689.         ydim    =    ( SHRINK(16 * ynum, yzoom) ) >> 16;
  690.  
  691.         /* the y pos passed to the hardware is the that of the last line
  692.            we need the y pos of the first line  */
  693.         sy -= ydim;
  694.  
  695.         if (    ((sx+xdim-1) < xmin) || (sx > xmax) ||
  696.                 ((sy+ydim-1) < ymin) || (sy > ymax)        )    continue;
  697.  
  698.         code    =    READ_WORD(&source[0x0C]);
  699.         attr    =    READ_WORD(&source[0x0E]);
  700.         color    =    SPRITE_COLOR(attr);
  701.  
  702.         for (i = 0; i < xnum * ynum; i++)
  703.             colmask[color] |= pen_usage[(code + i) % total_elements];
  704.     }
  705.  
  706.     for (color = 0; color < SPRITE_COLOR_CODES; color++)
  707.      for (i = 0; i < (16-1); i++)    // pen 15 is transparent
  708.       if (colmask[color] & (1 << i)) palette_used_colors[16 * color + i + color_codes_start] = PALETTE_COLOR_USED;
  709. }
  710.  
  711.  
  712.  
  713.  
  714. /*
  715.     Draw sprites, in the given priority range, to a bitmap.
  716.  
  717.     Priorities between 0 and 15 cover sprites whose priority nibble
  718.     is between 0 and 15. Priorities between    0+16 and 15+16 cover
  719.     sprites whose priority nibble is between 0 and 15 and whose
  720.     colour code's high bit is set.
  721.  
  722.     Sprite Data:
  723.  
  724.     Offset        Data
  725.  
  726.     00         fed- ---- ---- ----        unused?
  727.              ---c ---- ---- ----        Don't display this sprite
  728.             ---- ba98 ---- ----        unused?
  729.             ---- ---- 7654 ----        Number of tiles along Y, minus 1 (1-16)
  730.             ---- ---- ---- 3210        Number of tiles along X, minus 1 (1-16)
  731.  
  732.     02/04     fed- ---- ---- ----        unused?
  733.              ---c ---- ---- ----        Flip X/Y
  734.             ---- ba98 ---- ----        unused?
  735.             ---- ---- 7654 3210        X/Y zoom
  736.  
  737.     06/08    fedc ba-- ---- ----        unused?
  738.             ---- --98 7654 3210        X/Y position
  739.  
  740.     0A        ?
  741.  
  742.     0C        Code
  743.  
  744.     0E
  745.             fed- ---- ---- ----        unused?
  746.             ---c ---- ---- ----        used!
  747.             ---- ba98 ---- ----        Priority
  748.             ---- ---- 7--- ----        unused?
  749.             ---- ---- -654 3210        Color
  750.  
  751. */
  752. static void cischeat_draw_sprites(struct osd_bitmap *bitmap , int priority1, int priority2)
  753. {
  754.     int x, y, sx, sy;
  755.     int xzoom, yzoom, xscale, yscale, flipx, flipy;
  756.     int xdim, ydim, xnum, ynum;
  757.     int xstart, ystart, xend, yend, xinc, yinc;
  758.     int code, attr, color, size;
  759.  
  760.     int min_priority, max_priority, high_sprites;
  761.  
  762.     unsigned char        *source    = spriteram;
  763.     const unsigned char *finish    = source + 0x1000;
  764.  
  765.  
  766.     /* Move the priority values in place */
  767.     high_sprites = (priority1 >= 16) | (priority2 >= 16);
  768.     priority1 = (priority1 & 0x0f) * 0x100;
  769.     priority2 = (priority2 & 0x0f) * 0x100;
  770.  
  771.     if (priority1 < priority2)    {    min_priority = priority1;    max_priority = priority2; }
  772.     else                        {    min_priority = priority2;    max_priority = priority1; }
  773.  
  774.     for (; source < finish; source += 0x10 )
  775.     {
  776.         size    =    READ_WORD(&source[0x00]);
  777.         if (size & 0x1000)    continue;
  778.  
  779.         /* number of tiles */
  780.         xnum    =    ( (size & 0x0f) >> 0 ) + 1;
  781.         ynum    =    ( (size & 0xf0) >> 4 ) + 1;
  782.  
  783.         xzoom    =    READ_WORD(&source[0x02]);
  784.         yzoom    =    READ_WORD(&source[0x04]);
  785.         flipx    =    xzoom & 0x1000;
  786.         flipy    =    yzoom & 0x1000;
  787.  
  788.         sx        =    READ_WORD(&source[0x06]);
  789.         sy        =    READ_WORD(&source[0x08]);
  790.         SIGN_EXTEND_POS(sx)
  791.         SIGN_EXTEND_POS(sy)
  792.  
  793.         /* use fixed point values (16.16), for accuracy */
  794.         sx <<= 16;
  795.         sy <<= 16;
  796.  
  797.         /* dimension of a tile after zoom */
  798. #ifdef MAME_DEBUG
  799.         if ( keyboard_pressed(KEYCODE_Z) && keyboard_pressed(KEYCODE_M) )
  800.         {
  801.             xdim    =    16 << 16;
  802.             ydim    =    16 << 16;
  803.         }
  804.         else
  805. #endif
  806.         {
  807.             xdim    =    SHRINK(16,xzoom);
  808.             ydim    =    SHRINK(16,yzoom);
  809.         }
  810.  
  811.         if ( ( (xdim / 0x10000) == 0 ) || ( (ydim / 0x10000) == 0) )    continue;
  812.  
  813.         /* the y pos passed to the hardware is the that of the last line
  814.            we need the y pos of the first line  */
  815.         sy -= (ydim * ynum);
  816.  
  817.         code    =    READ_WORD(&source[0x0C]);
  818.         attr    =    READ_WORD(&source[0x0E]);
  819.         color    =    SPRITE_COLOR(attr);
  820.  
  821.         /* high byte is a priority information */
  822.         if ( ((attr & 0x700) < min_priority) || ((attr & 0x700) > max_priority) )
  823.             continue;
  824.  
  825.         if ( high_sprites && (!(color & (SPRITE_COLOR_CODES/2))) )
  826.             continue;
  827.  
  828. #ifdef MAME_DEBUG
  829. if ( (debugsprites) && ( ((attr & 0x0300)>>8) != (debugsprites-1) ) )     { continue; };
  830. #endif
  831.  
  832.         xscale = xdim / 16;
  833.         yscale = ydim / 16;
  834.  
  835.  
  836.         /* let's approximate to the nearest greater integer value
  837.            to avoid holes in between tiles */
  838.         if (xscale & 0xffff)    xscale += (1<<16)/16;
  839.         if (yscale & 0xffff)    yscale += (1<<16)/16;
  840.  
  841.  
  842.         if (flipx)    { xstart = xnum-1;  xend = -1;    xinc = -1; }
  843.         else        { xstart = 0;       xend = xnum;  xinc = +1; }
  844.  
  845.         if (flipy)    { ystart = ynum-1;  yend = -1;    yinc = -1; }
  846.         else        { ystart = 0;       yend = ynum;  yinc = +1; }
  847.  
  848.         for (y = ystart; y != yend; y += yinc)
  849.         {
  850.             for (x = xstart; x != xend; x += xinc)
  851.             {
  852.                 drawgfxzoom(bitmap,Machine->gfx[5],
  853.                             code++,
  854.                             color,
  855.                             flipx,flipy,
  856.                             (sx + x * xdim) / 0x10000, (sy + y * ydim) / 0x10000,
  857.                             &Machine->drv->visible_area,
  858.                             TRANSPARENCY_PEN,15,
  859.                             xscale, yscale );
  860.             }
  861.         }
  862.  
  863. #ifdef MAME_DEBUG
  864.         if ( keyboard_pressed(KEYCODE_Z) && keyboard_pressed(KEYCODE_N) )
  865.         {
  866.             struct DisplayText dt[3];
  867.             char buf[40],buf1[40];
  868.  
  869.             dt[0].text = buf;    dt[1].text = buf1;    dt[2].text = 0;
  870.             dt[0].color = dt[1].color = UI_COLOR_NORMAL;
  871.             dt[0].x = sx / 0x10000;    dt[1].x = dt[0].x;
  872.             dt[0].y = sy / 0x10000;    dt[1].y = dt[0].y + 8;
  873.  
  874.             sprintf(buf, "A:%04X",attr);
  875.             sprintf(buf1,"Z:%04X",xzoom);
  876.             displaytext(Machine->scrbitmap,dt,0,0);
  877.         }
  878. #endif
  879.  
  880.     }    /* end sprite loop */
  881.  
  882. }
  883.  
  884.  
  885.  
  886.  
  887. /***************************************************************************
  888.  
  889.                                 Screen Drawing
  890.  
  891. ***************************************************************************/
  892.  
  893. #define CISCHEAT_LAYERSCTRL \
  894. debugsprites = 0; \
  895. if (keyboard_pressed(KEYCODE_Z)) \
  896. { \
  897.     int msk = 0; \
  898.     if (keyboard_pressed(KEYCODE_Q))    { msk |= 0xffc1;} \
  899.     if (keyboard_pressed(KEYCODE_W))    { msk |= 0xffc2;} \
  900.     if (keyboard_pressed(KEYCODE_E))    { msk |= 0xffc4;} \
  901.     if (keyboard_pressed(KEYCODE_A))    { msk |= 0xffc8; debugsprites = 1;} \
  902.     if (keyboard_pressed(KEYCODE_S))    { msk |= 0xffc8; debugsprites = 2;} \
  903.     if (keyboard_pressed(KEYCODE_D))    { msk |= 0xffc8; debugsprites = 3;} \
  904.     if (keyboard_pressed(KEYCODE_F))    { msk |= 0xffc8; debugsprites = 4;} \
  905.     if (keyboard_pressed(KEYCODE_R))    { msk |= 0xffd0;} \
  906.     if (keyboard_pressed(KEYCODE_T))    { msk |= 0xffe0;} \
  907.  \
  908.     if (msk != 0) megasys1_active_layers &= msk; \
  909. } \
  910. \
  911. { \
  912.     static int show_unknown; \
  913.     if ( keyboard_pressed(KEYCODE_Z) && keyboard_pressed(KEYCODE_U) ) \
  914.     { \
  915.         while (keyboard_pressed(KEYCODE_U)); \
  916.         show_unknown ^= 1; \
  917.     } \
  918.  \
  919.     if (show_unknown) \
  920.     { \
  921.         char buf[80]; \
  922.         sprintf(buf, "0:%04X 2:%04X 4:%04X 6:%04X", \
  923.                     READ_WORD(&megasys1_vregs[0x0000]), \
  924.                     READ_WORD(&megasys1_vregs[0x0002]), \
  925.                     READ_WORD(&megasys1_vregs[0x0004]), \
  926.                     READ_WORD(&megasys1_vregs[0x0006]) \
  927.                 ); \
  928.         usrintf_showmessage(buf); \
  929.     } \
  930. }
  931.  
  932.  
  933. /**************************************************************************
  934.                                 [ Cisco Heat ]
  935. **************************************************************************/
  936.  
  937. void cischeat_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  938. {
  939.     int megasys1_active_layers1, flag;
  940.  
  941. #ifdef MAME_DEBUG
  942.     megasys1_active_layers = READ_WORD(&megasys1_vregs[0x2400]);
  943.     if (megasys1_active_layers == 0)    megasys1_active_layers = 0x3f;
  944. #else
  945.     megasys1_active_layers = 0x3f;
  946. #endif
  947.  
  948.     megasys1_active_layers1 = megasys1_active_layers;
  949.  
  950. #ifdef MAME_DEBUG
  951.     CISCHEAT_LAYERSCTRL
  952. #endif
  953.  
  954.     MEGASYS1_TMAP_SET_SCROLL(0)
  955.     MEGASYS1_TMAP_SET_SCROLL(1)
  956.     MEGASYS1_TMAP_SET_SCROLL(2)
  957.  
  958.     MEGASYS1_TMAP_UPDATE(0)
  959.     MEGASYS1_TMAP_UPDATE(1)
  960.     MEGASYS1_TMAP_UPDATE(2)
  961.  
  962.     palette_init_used_colors();
  963.  
  964.     if (megasys1_active_layers & 0x08)    cischeat_mark_sprite_colors();
  965.     if (megasys1_active_layers & 0x10)    cischeat_mark_road_colors(0);    // road 0
  966.     if (megasys1_active_layers & 0x20)    cischeat_mark_road_colors(1);    // road 1
  967.  
  968.     if (palette_recalc())    tilemap_mark_all_pixels_dirty(ALL_TILEMAPS);
  969.  
  970.     MEGASYS1_TMAP_RENDER(0)
  971.     MEGASYS1_TMAP_RENDER(1)
  972.     MEGASYS1_TMAP_RENDER(2)
  973.  
  974.     osd_clearbitmap(Machine->scrbitmap);
  975.  
  976.                                         /* bitmap, road, priority, transparency */
  977.     if (megasys1_active_layers & 0x10)    cischeat_draw_road(bitmap,0,7,5,TRANSPARENCY_NONE);
  978.     if (megasys1_active_layers & 0x20)    cischeat_draw_road(bitmap,1,7,5,TRANSPARENCY_PEN);
  979.  
  980.     flag = 0;
  981.     MEGASYS1_TMAP_DRAW(0)
  982. //    else    osd_clearbitmap(Machine->scrbitmap);
  983.     MEGASYS1_TMAP_DRAW(1)
  984.  
  985.     if (megasys1_active_layers & 0x08)    cischeat_draw_sprites(bitmap,15,3);
  986.     if (megasys1_active_layers & 0x10)    cischeat_draw_road(bitmap,0,4,1,TRANSPARENCY_PEN);
  987.     if (megasys1_active_layers & 0x20)    cischeat_draw_road(bitmap,1,4,1,TRANSPARENCY_PEN);
  988.     if (megasys1_active_layers & 0x08)    cischeat_draw_sprites(bitmap,2,2);
  989.     if (megasys1_active_layers & 0x10)    cischeat_draw_road(bitmap,0,0,0,TRANSPARENCY_PEN);
  990.     if (megasys1_active_layers & 0x20)    cischeat_draw_road(bitmap,1,0,0,TRANSPARENCY_PEN);
  991.     if (megasys1_active_layers & 0x08)    cischeat_draw_sprites(bitmap,1,0);
  992.     MEGASYS1_TMAP_DRAW(2)
  993.  
  994.     /* for the map screen */
  995.     if (megasys1_active_layers & 0x08)    cischeat_draw_sprites(bitmap,0+16,0+16);
  996.  
  997.  
  998.     megasys1_active_layers = megasys1_active_layers1;
  999. }
  1000.  
  1001.  
  1002.  
  1003.  
  1004.  
  1005. /**************************************************************************
  1006.                             [ F1 GrandPrix Star ]
  1007. **************************************************************************/
  1008.  
  1009.  
  1010. void f1gpstar_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  1011. {
  1012.     int megasys1_active_layers1, flag;
  1013.  
  1014. #ifdef MAME_DEBUG
  1015.     megasys1_active_layers = READ_WORD(&megasys1_vregs[0x2400]);
  1016.     if (megasys1_active_layers == 0)    megasys1_active_layers = 0x3f;
  1017. #else
  1018.     megasys1_active_layers = 0x3f;
  1019. #endif
  1020.  
  1021.     megasys1_active_layers1 = megasys1_active_layers;
  1022.  
  1023. #ifdef MAME_DEBUG
  1024.     CISCHEAT_LAYERSCTRL
  1025. #endif
  1026.  
  1027.     MEGASYS1_TMAP_SET_SCROLL(0)
  1028.     MEGASYS1_TMAP_SET_SCROLL(1)
  1029.     MEGASYS1_TMAP_SET_SCROLL(2)
  1030.  
  1031.     MEGASYS1_TMAP_UPDATE(0)
  1032.     MEGASYS1_TMAP_UPDATE(1)
  1033.     MEGASYS1_TMAP_UPDATE(2)
  1034.  
  1035.     palette_init_used_colors();
  1036.  
  1037.     if (megasys1_active_layers & 0x08)    cischeat_mark_sprite_colors();
  1038.     if (megasys1_active_layers & 0x10)    f1gpstar_mark_road_colors(0);    // road 0
  1039.     if (megasys1_active_layers & 0x20)    f1gpstar_mark_road_colors(1);    // road 1
  1040.  
  1041.     if (palette_recalc())    tilemap_mark_all_pixels_dirty(ALL_TILEMAPS);
  1042.  
  1043.     MEGASYS1_TMAP_RENDER(0)
  1044.     MEGASYS1_TMAP_RENDER(1)
  1045.     MEGASYS1_TMAP_RENDER(2)
  1046.  
  1047.     osd_clearbitmap(Machine->scrbitmap);
  1048.  
  1049. /*    1: clouds 5, grad 7, road 0        2: clouds 5, grad 7, road 0, tunnel roof 0 */
  1050.  
  1051.     /* NOTE: TRANSPARENCY_NONE isn't supported by drawgfxzoom    */
  1052.     /* (the function used in f1gpstar_drawroad to draw the road) */
  1053.  
  1054.     /* road 1!! 0!! */                    /* bitmap, road, min_priority, max_priority, transparency */
  1055.     if (megasys1_active_layers & 0x20)    f1gpstar_draw_road(bitmap,1,6,7,TRANSPARENCY_PEN);
  1056.     if (megasys1_active_layers & 0x10)    f1gpstar_draw_road(bitmap,0,6,7,TRANSPARENCY_PEN);
  1057.  
  1058.     flag = 0;
  1059.     MEGASYS1_TMAP_DRAW(0)
  1060. //    else    osd_clearbitmap(Machine->scrbitmap);
  1061.     MEGASYS1_TMAP_DRAW(1)
  1062.  
  1063.     /* road 1!! 0!! */                    /* bitmap, road, min_priority, max_priority, transparency */
  1064.     if (megasys1_active_layers & 0x20)    f1gpstar_draw_road(bitmap,1,1,5,TRANSPARENCY_PEN);
  1065.     if (megasys1_active_layers & 0x10)    f1gpstar_draw_road(bitmap,0,1,5,TRANSPARENCY_PEN);
  1066.  
  1067.     if (megasys1_active_layers & 0x08)    cischeat_draw_sprites(bitmap,15,2);
  1068.  
  1069.     /* road 1!! 0!! */                    /* bitmap, road, min_priority, max_priority, transparency */
  1070.     if (megasys1_active_layers & 0x20)    f1gpstar_draw_road(bitmap,1,0,0,TRANSPARENCY_PEN);
  1071.     if (megasys1_active_layers & 0x10)    f1gpstar_draw_road(bitmap,0,0,0,TRANSPARENCY_PEN);
  1072.  
  1073.     if (megasys1_active_layers & 0x08)    cischeat_draw_sprites(bitmap,1,1);
  1074.     MEGASYS1_TMAP_DRAW(2)
  1075.     if (megasys1_active_layers & 0x08)    cischeat_draw_sprites(bitmap,0,0);
  1076.  
  1077.  
  1078.     megasys1_active_layers = megasys1_active_layers1;
  1079. }
  1080.